﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

using Flagwind.Runtime.Serialization;
using Flagwind.Externals.Storages.Configuration;

namespace Flagwind.Externals.Storages
{
	public class StorageClient
	{
		#region 公共属性

		/// <summary>
		/// 获取或设置配置选项。
		/// </summary>
		public GenericOption Option
		{
			get;
			set;
		}

		#endregion

		#region 公共方法

		public async Task<FileUploadResult> Upload(string directory, string fileName, Stream fileStream)
		{
			if(string.IsNullOrWhiteSpace(fileName))
				throw new ArgumentNullException(nameof(fileName));

			if(fileStream == null || fileStream.Length == 0)
				throw new ArgumentNullException(nameof(fileStream));

			var url = this.Option.FileApi;

			// 设置目录
			if(!string.IsNullOrWhiteSpace(directory))
				url = string.Format("{0}?directory={1}", url, directory);

			using(var client = new HttpClient())
			{
				using(var content = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture)))
				{
					// 将文件流添加至请求内容中
					content.Add(new StreamContent(fileStream), fileName, fileName);

					// 发送 POST 上传请求
					var response = await client.PostAsync(url, content);

					if(response.StatusCode == HttpStatusCode.OK)
					{
						var responseText = await response.Content.ReadAsStringAsync();

						// 反序列化 JSON 对象
						var results = Serializer.Json.Deserialize<List<FileUploadResult>>(responseText);

						return results.FirstOrDefault();
					}
				}
			}

			return null;
		}

		/// <summary>
		/// 下载指定路径的文件。
		/// </summary>
		/// <param name="path">指定要下载的文件的全路径或相对路径或绝对路径（绝对路径以/斜杠打头）。</param>
		/// <returns>指定路径的文件流。</returns>
		public async Task<Stream> Download(string path)
		{
			if(string.IsNullOrWhiteSpace(path))
				throw new ArgumentNullException(nameof(path));

			var url = string.Format("{0}?path={1}", this.Option.FileApi, path);

			using(var client = new HttpClient())
			{
				var response = await client.GetAsync(url);

				if(response.StatusCode == HttpStatusCode.OK)
				{
					var stream = await response.Content.ReadAsStreamAsync();

					return stream;
				}
			}

			return null;
		}

		/// <summary>
		/// 删除指定路径的文件。
		/// </summary>
		/// <param name="path">指定要删除的文件的全路径或相对路径或绝对路径（绝对路径以/斜杠打头）。</param>
		/// <returns>删除是否成功。</returns>
		public async Task<bool> Delete(string path)
		{
			if(string.IsNullOrWhiteSpace(path))
				throw new ArgumentNullException(nameof(path));

			var url = string.Format("{0}?path={1}", this.Option.FileApi, path);
				
			using(var client = new HttpClient())
			{
				var response = await client.DeleteAsync(url);

				if(response.StatusCode == HttpStatusCode.OK)
				{
					var responseText = await response.Content.ReadAsStringAsync();

					return Flagwind.Common.Convert.ConvertValue<bool>(responseText);
				}
			}

			return false;
		}

		#endregion
	}
}
